package com.svconnect.transport;

import java.lang.reflect.Type;

import org.apache.http.HttpException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import com.svconnect.model.soap.SoapRequestEnvelope;
import com.svconnect.model.soap.SoapResponseEnvelope;
import com.svconnect.util.Log;

public class HttpTransport extends Transport {

	public HttpTransport(String url) {
		super(url);
	}

	public HttpTransport(String url, String username, String password) {
		super(url, username, password);
	}

	@Override
	public <T> T call(SoapRequestEnvelope envelope, Type returnType, Class<?>[] exceptions) throws Exception {
		
		Log.v("SOAP Request Envelope");
		Log.v("\n"+envelope.toString());

		HttpClient httpClient = new DefaultHttpClient();

		HttpPost httpPost = new HttpPost(this.getUrl());
		httpPost.setEntity(envelope.getHttpEntity());
		httpPost.setHeader("Content-Type", "text/xml; charset=UTF-8");
		httpPost.setHeader("SOAPAction", envelope.getAction());
	    
		HttpParams httpParameters = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(httpParameters,this.getConnectionTimeout());
		HttpConnectionParams.setSoTimeout(httpParameters,this.getSocketTimeout());
		
		BasicHttpResponse response = (BasicHttpResponse) httpClient
				.execute(httpPost);
		int statusCode = response.getStatusLine().getStatusCode();   
		SoapResponseEnvelope respEnv = new SoapResponseEnvelope(response.getEntity());

		Log.i(String.format("Response came (HTTP %s)",statusCode));
	    Log.v("SOAP Response Envelope");
	    Log.v("\n"+respEnv.toString());
		
		if (statusCode!=200) {
			RuntimeException ex = respEnv.getFault(exceptions);
			if (ex!=null)
				throw ex;
			throw new HttpException("HTTP "+statusCode);
		}
		
		return respEnv.getResponse(returnType);
	}

}
